package com.example.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.starter.mybatis.util.PageUtil;
import com.example.starter.util.ExceptionUtil;
import com.example.system.convert.DictConvert;
import com.example.system.dto.DictDto;
import com.example.system.dto.DictItemDto;
import com.example.system.dto.DictParam;
import com.example.system.entity.Dict;
import com.example.system.entity.DictItem;
import com.example.system.mapper.DictItemMapper;
import com.example.system.mapper.DictMapper;
import com.example.system.service.IDictService;
import com.example.system.vo.DictItemVo;
import com.example.system.vo.DictVo;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 *
 * @author 王令
 * @since 2022-10-28
 */
@Service
@RequiredArgsConstructor
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements IDictService {

    private final DictItemMapper itemMapper;

    @Override
    public void create(DictDto dictDto) {
        Dict dict = DictConvert.INSTANCE.toDict(dictDto);
        assertUniqueRecord(dict);
        this.save(dict);
    }

    @Transactional
    @Override
    public void addItem(Long id, List<DictItemDto> itemDtos) {
        itemMapper.delete(Wrappers.<DictItem>lambdaQuery().eq(DictItem::getDictId, id));
        if (ObjectUtil.isNotEmpty(itemDtos)) {
            itemMapper.addItem(id, itemDtos);
        }
    }

    @Override
    public void update(DictDto dictDto) {
        Dict dict = DictConvert.INSTANCE.toDict(dictDto);
        assertUniqueRecord(dict);
        this.updateById(dict);
    }

    @Override
    public void deleteById(Long id) {
        assertSafeDelete(id);
        this.removeById(id);
    }

    @Override
    public Page<DictVo> listWithPagination(Pageable pageable, DictParam param) {
        return baseMapper.listWithPagination(PageUtil.getPage(pageable), param);
    }

    @Override
    public List<DictItemVo> listAllItemVoByDictId(Long id) {
        return DictConvert.INSTANCE.toDictItemVoList(itemMapper.selectList(Wrappers.<DictItem>lambdaQuery().eq(DictItem::getDictId, id)));
    }

    private void assertUniqueRecord(Dict dict) {
        LambdaQueryWrapper<Dict> wrapper = Wrappers.<Dict>lambdaQuery()
                .eq(Dict::getCode, dict.getCode())
                .ne(dict.getId() != null, Dict::getId, dict.getId());
        Dict one = baseMapper.selectOne(wrapper);
        if (one != null) {
            throw ExceptionUtil.wrap("字典编码已存在");
        }
    }

    private void assertSafeDelete(Long id) {
        Integer count = itemMapper.selectCount(Wrappers.<DictItem>lambdaQuery().eq(DictItem::getDictId, id));
        if (count != null && count > 0) {
            throw ExceptionUtil.wrap("存在字典项，不能删除");
        }
    }
}
